package com.heima.utils.common;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

@SuppressWarnings("ALL")
public class ProtostuffUtil {
    // 避免每次序列化都重新申请Buffer空间
    private static final ThreadLocal<LinkedBuffer> BUFFER_THREAD_LOCAL = ThreadLocal.withInitial(() ->
        LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE)
    );

    /**
     * 序列化对象
     * @param obj 要序列化的对象
     * @return 序列化后的字节数组
     */
    public static <T> byte[] serialize(T obj) {
        if (obj == null) {
            return null;
        }
        // 获取运行时Schema
        Schema<T> schema = (Schema<T>) RuntimeSchema.getSchema(obj.getClass());
         // 使用可重用的缓冲区（关键优化）
        LinkedBuffer buffer = BUFFER_THREAD_LOCAL.get();
        try {
            return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
        } finally {
            buffer.clear(); // 清理缓冲区以备重用
        }
    }

    /**
     * 反序列化对象
     * @param data 序列化后的字节数组
     * @param clazz 目标类
     * @return 反序列化后的对象
     */
    public static <T> T deserialize(byte[] data, Class<T> clazz) {
        if (data == null || data.length == 0) {
            return null;
        }
        Schema<T> schema = RuntimeSchema.getSchema(clazz);
        // 创建目标对象实例
        T obj = schema.newMessage();
        // 合并数据到对象
        ProtostuffIOUtil.mergeFrom(data, obj, schema);
        return obj;
    }
}